#pragma once
#include <xhash>
#include "common/download.h"
#include "ipcproxy/proxy.h"
#include "utils.hpp"
#include "notify_hander.h"

typedef int (__stdcall *PProxyMain)(HINSTANCE,	IWorkProvider**);

namespace stdext {
template <class T>
inline void hash_combine(std::size_t& seed, T const& v) {
  seed ^= stdext::hash_value(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
//--------------------------------------------------------------------------------------------
struct UrlFilePair {
  const wchar_t* url;
  const wchar_t* file;
};

const UrlFilePair urls[] = {
  {L"http://10.2.78.137/backup-xntalk/4.67.1/4.67.1.31/rrsetup-1.exe", L"rrsetup-1.exe"},
  {L"http://soft.opi-corp.com/DownSoft/get.php?softid=427&pathid=0", L"iPhone4,1_5.0_9A334_Restore.ipsw"},
  {L"http://down.360safe.com/inst.exe", L"inst.exe"},
	{L"http://down.360safe.com/bizhi/360wallpaper_2.1beta5.exe", L"360wallpaper_2.1beta5.exe"},
	{L"http://dl.360safe.com/360zip_setup_3.0.0.2015.exe", L"360zip_setup_3.0.0.2015.exe"},
  {L"http://unvalid_page.com/", L"unvalid.exe"}
};

UrlRequestData MakeUrlRequest(const UrlFilePair urlfile) {
  UrlRequestData info;
  wcscpy_s(info.request_url, urlfile.url);
  std::wstring file = L"D:\\download\\";
  file += urlfile.file;
  wcscpy_s(info.save_path, file.c_str());
  info.start_position = 0;
  return info;
}
//---------------------------------------------------------------------------------------------
class CMainDlg : public CDialogImpl<CMainDlg> {
public:
	enum { IDD = IDD_MAINDLG };

  CMainDlg() {
    provider_ = NULL;
    download_ = NULL;
  }

	BEGIN_MSG_MAP(CMainDlg)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_ID_HANDLER(IDOK, OnOK)
		COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
    COMMAND_HANDLER(IDC_BUTTON1, BN_CLICKED, OnBnClickedButton1)
  END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// center the dialog on the screen
		CenterWindow();

		// set icons
		HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
			IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
		SetIcon(hIcon, TRUE);
		HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
			IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
		SetIcon(hIconSmall, FALSE);
    hash_ = 0;
    handler_.SetHintCtrl(GetDlgItem(IDC_EDIT_HINT));
    Prepare();

		return TRUE;
	}

	LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
    UrlRequestData info = MakeUrlRequest(urls[2]);
    stdext::hash_combine(hash_, info.request_url);
    stdext::hash_combine(hash_, info.save_path);
    stdext::hash_combine(hash_, ::GetCurrentProcessId());
		download_->AddUrlRequest(hash_, &info);


		size_t hash = 1;
		info = MakeUrlRequest(urls[3]);
		stdext::hash_combine(hash, info.request_url);
		stdext::hash_combine(hash, info.save_path);
		stdext::hash_combine(hash, ::GetCurrentProcessId());
		download_->AddUrlRequest(hash, &info);

		hash = 0;
		info = MakeUrlRequest(urls[4]);
		stdext::hash_combine(hash, info.request_url);
		stdext::hash_combine(hash, info.save_path);
		stdext::hash_combine(hash, ::GetCurrentProcessId());
		download_->AddUrlRequest(hash, &info);


		return 0;
	}

  LRESULT OnBnClickedButton1(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
    download_->CancelUrlRequest(hash_);
    return 0;
  }

	LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
    if (provider_) {
      provider_->Cleanup();
    }
		EndDialog(wID);
		return 0;
	}

private:
  void Prepare() {
    if (!provider_) {
      wchar_t path[MAX_PATH];
      ::GetModuleFileNameW(NULL, path, _countof(path));
      ::PathRemoveFileSpecW(path);
      ::PathAppendW(path, L"ipcproxy.dll");
      if (library_.Load(path)) {
        PProxyMain proxy_main = (PProxyMain)library_.GetProcAddress("ProxyMain");
        if (proxy_main) {
          proxy_main(GetModuleHandleW(NULL), &provider_);
          if (provider_) {
            provider_->Init();
            download_ = provider_->GetDownload();
            download_->SetNotifyDelegate(&handler_);
          }
        }
      }
    }
  }

private:
  size_t hash_;
  AuxLoadLibrary  library_;
  IWorkProvider*  provider_;
  IDownloadProxy* download_;
  NotifyHandler handler_;  
};
